package kalambury.client;

import kalambury.srv.PlayerInfo;
import kalambury.srv.PlayerStatus;

import javax.swing.*;
import javax.swing.event.ListDataListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: ufoq
 * Date: 19.11.12
 * Time: 22:47
 * To change this template use File | Settings | File Templates.
 */

/**
 * klasa implementująca panel gry
 */
public class GamePanel extends javax.swing.JPanel {

    /**
     * klasa implementująca model listy graczy
     */
    private static final class ListPlayersDataModel implements ListModel {
        List<PlayerInfo> players;

        /**
         * konstruktor
         * @param players lista graczy
         */
        public ListPlayersDataModel(List<PlayerInfo> players) {
            this.players = players;
        }

        /**
         * pobierz ilość danych
         * @return ilość danych
         */
        public int getSize() {
            return players.size();
        }

        /**
         * zwróc element o danym indeksie
         * @param index indeks
         * @return element
         */
        public Object getElementAt(int index) {
            PlayerInfo pi = players.get(index);
            String status = pi.status==PlayerStatus.Drawer?"Rysuje":"Zgaduje";
            return pi.name+": "+status+" ("+pi.score+" punktów)";
        }

        public void addListDataListener(ListDataListener l) {
        }

        public void removeListDataListener(ListDataListener l) {
        }

        public void setPlayers(List<PlayerInfo> players) {
            this.players    = players;
        }
    }

    /**
     * klasa pozwalająca reagować na zdarzenia gry
     */
    private final class GamePanelConnectionEvents implements GameConnection.GameConnectionEventsListener {

        /**
         * zdarzenie otrzymania obrazka
         * @param img obrazek
         */
        public void onImageReceived(Image img) {
            drawerPanel.setImage(img);
        }

        /**
         * zdarzenie otrzymania propozycji rozwiązania
         * @param playerName gracz
         * @param suggestion propozycja
         * @param valid poprawność propozycji
         */
        public void onPasswordSuggestionReceived(String playerName, String suggestion, boolean valid) {
            putSuggestion(String.format("%s : %s -> %s",playerName,suggestion,valid?"dobrze":"źle"));
        }

        /**
         * zdarzenie otrzymania listy graczy
         * @param players
         */
        public void onPlayersListReceived(List<PlayerInfo> players) {
            p("received list");
            listPlayers.setModel(new ListPlayersDataModel(players));
        }

        /**
         * zdarzenie otrzymania informacji o graczu
         * @param status stan gracza
         * @param additionalInfo dodatkowe informacje
         */
        public void onPlayerStatusReceived(PlayerStatus status, String additionalInfo) {
            if(status == PlayerStatus.Drawer){
                btnSendImage.setEnabled(true);
                btnSendText.setEnabled(false);
                textFieldSuggestion.setEnabled(false);

                drawerPanel.setMayDrawing(true);
                labelActualPassword.setText("Aktualne hasło: "+additionalInfo);
                labelNowDrawing.setText("Teraz rysuje: "+gameConnection.getMyName());
                JOptionPane.showMessageDialog(GamePanel.this, "Teraz Ty rysujesz");
            } else {
                btnSendImage.setEnabled(false);
                btnSendText.setEnabled(true);
                textFieldSuggestion.setEnabled(true);

                drawerPanel.setMayDrawing(false);
                labelActualPassword.setText("");
                labelNowDrawing.setText("Teraz rysuje: "+additionalInfo);
            }
        }

        /**
         * zdarzenie zmiany rysującego
         * @param name nazwa nowego rysującego
         */
        public void onDrawerChanged(String name) {
            drawerPanel.clear();
            labelNowDrawing.setText("Teraz rysuje: "+name);
        }
    }

    /**
     * wypisz na wyjście
     * @param s tekst
     */
    private static void p(String s){
        System.out.println(s);
    }

    private final ClientApplication app;
    private GameConnection gameConnection;
    private ArrayList<String> sugs = new ArrayList<String>();

    /**
     * Creates new form ClientPanel
     */
    public GamePanel(ClientApplication app, GameConnection gameConnection) {
        this.app = app;
        this.gameConnection = gameConnection;
        System.out.println("init game panel");
        initComponents();
        System.out.println("initialised game panel");
        initCustom();
    }

    private GamePanel() {
        this(null,null);
    }

    /**
     * ustaw propozycje
     */
    private void putSuggestion(String s){
        sugs.add(s);
        while(sugs.size()>5){
            sugs.remove(0);
        }
        renderSuggestions();
    }

    /**
     * wyświetl propozycje
     */
    private void renderSuggestions() {
        String s = "";
        for(String sug : sugs){
            s += sug + "\n";
        }
        labelConversation.setText(s);
    }

    /**
     * dodatkowa inicjalizacja GUI
     */
    private void initCustom() {
        labelActualPassword.setText("");
        labelNowDrawing.setText("ładuję");
        renderSuggestions();

        gameConnection.setEventsListener(new GamePanelConnectionEvents());
        gameConnection.requestPlayerStatus();
        listPlayers.setModel(new ListPlayersDataModel(new ArrayList<PlayerInfo>()));
        gameConnection.requestPlayersList();

        initEvents();
    }

    /**
     * inicjalizacja obsługi zdarzeń
     */
    private void initEvents() {
        btnSendImage.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                gameConnection.sendImage(drawerPanel.getImage());
            }
        });

        ActionListener pushSuggestionAction = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String s= textFieldSuggestion.getText();
                textFieldSuggestion.setText("");
                gameConnection.sendSuggestion(s);
            }
        } ;

        btnSendText.addActionListener(pushSuggestionAction);
        textFieldSuggestion.addActionListener(pushSuggestionAction);

        btnLogout.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                gameConnection.disconnect();
                app.setActivePanel(new ClientForm(app));
            }
        });
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        drawerPanel = new DrawerPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        listPlayers = new javax.swing.JList();
        labelActualPassword = new javax.swing.JLabel();
        labelNowDrawing = new javax.swing.JLabel();
        textFieldSuggestion = new javax.swing.JTextField();
        labelPlayers = new javax.swing.JLabel();
        btnSendImage = new javax.swing.JButton();
        btnSendText = new javax.swing.JButton();
        jScrollPane2 = new javax.swing.JScrollPane();
        labelConversation = new javax.swing.JTextArea();
        btnLogout = new javax.swing.JButton();

        setMaximumSize(new java.awt.Dimension(600, 460));
        setMinimumSize(new java.awt.Dimension(600, 460));
        setPreferredSize(new java.awt.Dimension(600, 460));

        drawerPanel.setBackground(new java.awt.Color(255, 255, 255));
        drawerPanel.setMaximumSize(new java.awt.Dimension(400, 300));
        drawerPanel.setMinimumSize(new java.awt.Dimension(400, 300));
        drawerPanel.setPreferredSize(new java.awt.Dimension(400, 300));

        javax.swing.GroupLayout drawerPanelLayout = new javax.swing.GroupLayout(drawerPanel);
        drawerPanel.setLayout(drawerPanelLayout);
        drawerPanelLayout.setHorizontalGroup(
                drawerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGap(0, 0, Short.MAX_VALUE)
        );
        drawerPanelLayout.setVerticalGroup(
                drawerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGap(0, 300, Short.MAX_VALUE)
        );

        listPlayers.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane1.setViewportView(listPlayers);

        labelActualPassword.setText("Aktualne hasło:");

        labelNowDrawing.setText("Teraz rysuje:");

        labelPlayers.setText("Gracze:");

        btnSendImage.setText("Wyślij");

        btnSendText.setText("Wyślij");

        labelConversation.setEditable(false);
        labelConversation.setColumns(20);
        labelConversation.setRows(5);
        jScrollPane2.setViewportView(labelConversation);

        btnLogout.setText("Wyloguj");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                        .addComponent(textFieldSuggestion, javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                                .addComponent(labelNowDrawing, javax.swing.GroupLayout.PREFERRED_SIZE, 300, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                                .addComponent(btnSendImage, javax.swing.GroupLayout.DEFAULT_SIZE, 90, Short.MAX_VALUE))
                                        .addComponent(drawerPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addComponent(jScrollPane2))
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(layout.createSequentialGroup()
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                        .addComponent(jScrollPane1)
                                                        .addGroup(layout.createSequentialGroup()
                                                                .addGap(10, 10, 10)
                                                                .addComponent(labelActualPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 176, Short.MAX_VALUE)
                                                                .addGap(4, 4, 4)))
                                                .addContainerGap())
                                        .addGroup(layout.createSequentialGroup()
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(btnSendText)
                                                .addContainerGap())
                                        .addGroup(layout.createSequentialGroup()
                                                .addComponent(labelPlayers)
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                .addComponent(btnLogout))))
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                        .addComponent(drawerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                        .addComponent(labelPlayers)
                                                        .addComponent(btnLogout))
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(jScrollPane1)))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                        .addGroup(layout.createSequentialGroup()
                                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                                        .addComponent(labelNowDrawing)
                                                        .addComponent(btnSendImage))
                                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(jScrollPane2))
                                        .addComponent(labelActualPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 105, javax.swing.GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                        .addComponent(textFieldSuggestion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                        .addComponent(btnSendText))
                                .addContainerGap(20, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnLogout;
    private javax.swing.JButton btnSendImage;
    private javax.swing.JButton btnSendText;
    private DrawerPanel drawerPanel;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel labelActualPassword;
    private javax.swing.JTextArea labelConversation;
    private javax.swing.JLabel labelNowDrawing;
    private javax.swing.JLabel labelPlayers;
    private javax.swing.JList listPlayers;
    private javax.swing.JTextField textFieldSuggestion;
    // End of variables declaration//GEN-END:variables
}
